#! /usr/bin/python
# -*- coding: utf-8 -*-
import grpc
import os
import sys
import time
from dateutil.parser import * 
from datetime import datetime,timedelta

import global_var

from db_ctrl import *
from db_conf import *
from api import *

log = global_var.gl_log
DEMO = False

BASE_TABLE = "flattensys"
MAX_COUNT = 1000
MAX_INLET = 20
#EXP_FILE_NAME="plate_data.csv"
EXP_FILE_NAME="../webapp/dist/static/plate_data.csv"

def timestamp_from_objectid(objectid):
    result = 0
    try:
        tm = time.mktime(objectid.generation_time.timetuple())+28800
        #result = time.strftime("%Y%m%d%H%M%S",time.localtime(tm))
        result = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(tm))
    except:
        pass
    return result

class grpcServer(ProcDataServ_pb2_grpc.RealTimeProcServicer):
    def __init__(self):
        self.db = CDBProcessor() #data process: save, select
        self.db.connect()

    def GetPlateSetData(self, request, context):
        ret = ProcDataServ_pb2.PlateSetList()
        try:
            if DEMO:
                
                v1 = ProcDataServ_pb2.PlateSetInfo()
                v1.plate_id = "plate_00001"
                v1.material_id = "11230001"
                ret.set.append(v1)
                v2 = ProcDataServ_pb2.PlateSetInfo(plate_id="plate_00002")
                v2.material_id = "11230001"
                ret.set.append(v2)
                log.info("GetPlateSetData: ok")
            else:
                # if len(global_var.gl_dq_last):
                idx = 0

                #log.info("gl_dg_last :\n", global_var.gl_dq_last)
                # log.info("===================, type {},size: {}".format(type(global_var.gl_dq_last), len(global_var.gl_dq_last)))

                for _it in reversed(global_var.gl_dq_last):

                    val = ProcDataServ_pb2.PlateSetInfo()
                    
                    if _it.__contains__("plate_id"): val.plate_id = _it["plate_id"]
                    
                    if _it.__contains__("material_id"): val.material_id = _it["material_id"]
                    
                    if _it.__contains__("steel_grade"): val.steel_grade = _it["steel_grade"]
                    if _it.__contains__("length"): val.length=_it["length"]

                    if _it.__contains__("width"): val.width=_it["width"]
                    if _it.__contains__("thickness"): val.thickness=_it["thickness"]
                    if _it.__contains__("temp"): val.temp=_it["temp"]
                    if _it.__contains__("set_inlet"): val.set_inlet=_it["set_inlet"]
                    if _it.__contains__("set_outlet"): val.set_outlet=_it["set_outlet"]
                    if _it.__contains__("set_flexion"): val.set_flexion=_it["set_flexion"]
                    if _it.__contains__("full_length"): val.full_length = _it["full_length"]
                    if _it.__contains__("full_cross"): val.full_cross=_it["full_cross"]
                    if _it.__contains__("cross_1m"): val.cross_1m=_it["cross_1m"]
                    if _it.__contains__("length_1m"): val.length_1m=_it["length_1m"]
                    if _it.__contains__("length_2m"): val.length_2m=_it["length_2m"]
                    
                    ret.set.append(val)

                    idx += 1
                    if idx > 1:
                        break            
        except Exception as e:
            log.error("error::GetPlateSetData ", e)

         
        return ret

    def GetPlateActData(self, request, context):
        ret = ProcDataServ_pb2.PlateActList()
        try:
            tm_from = request.tm_from
            tm_to = request.tm_to

            #log.info("time: {} - {} ".format(request.tm_from,request.tm_to))
            if tm_from:
                dt_from = datetime.fromtimestamp(time.mktime(time.strptime(tm_from,"%Y%m%d%H%M%S")))
            if tm_to:
                dt_to = datetime.fromtimestamp(time.mktime(time.strptime(tm_to,"%Y%m%d%H%M%S")))
        
            if tm_from and tm_to:
                
                qry = {"ctime":{"$gte":dt_from, "$lte":dt_to}}
            elif tm_from:
                
                qry = {"ctime":{"$gte":dt_from}}
            elif tm_to:
                
                qry = {"ctime":{"$lte":dt_to}}
            else:
                dt_to = datetime.now()
                dt_from = dt_to - timedelta(hours=24)
                log.info("query time: {} - {}".format(dt_from, dt_to))
                qry = {"ctime":{"$gte":dt_from, "$lte":dt_to}}

            log.info("query data: {}".format( qry))
            results = self.db.findmany(BASE_TABLE, qry)
            log.info("query fin!, result type:{}, result count={}".format( type(results),len(results)))
            
            idx = 0
            act_list = []

            if len(EXP_FILE_NAME):
                f = open(EXP_FILE_NAME,"w")
                for _it in EXP_FIELD_NAMES:
                    f.write("{},".format(_it))
                f.write("\n")

            for i in range(len(results)-1,-1,-1):#逆排序
            #for _it in results:
            # for i in range(len(results)):
            
                # log.info("index {}".format(i))
                # it = results[i]
                _it = results[i]
                # log.info("{},{}".format(_it["plate_id"],_it["ctime"]))

                act_data = ProcDataServ_pb2.PlateActInfo()
                


                if _it.__contains__("plate_id"):  
                    act_data.plate_id = _it["plate_id"]
                else:
                    log.info("missing plate_id ")
                    continue
                
                ###################################################
                #判断是否是空过
                if _it.__contains__("L1_SET_DATA SET_LEVELLER_INLET[mm]"):
                    if _it["L1_SET_DATA SET_LEVELLER_INLET[mm]"] > MAX_INLET:
                        log.info("{} pass dummy".format(_it["plate_id"]))
                        continue

                ###################################################


                if _it.__contains__("steel grade"):
                    act_data.steel_grade=_it["steel grade"]
                else:
                    log.info("{},missing steel grade".format(_it["plate_id"]))
                    act_data.steel_grade = "Unknown"
                
                if _it.__contains__("plate length"):
                    act_data.length = _it["plate length"]
                if _it.__contains__("plate width"):
                    act_data.width = _it["plate width"]
                if _it.__contains__("plate thickness"):
                    act_data.thickness = _it["plate thickness"]
                if _it.__contains__("plate act temperature"):
                    act_data.temp = _it["plate act temperature"]

                if _it.__contains__("Leverler inlet manual"):
                    act_data.set_inlet_usr = _it["Leverler inlet manual"]
                if _it.__contains__("Leverler outlet manual"):
                    act_data.set_outlet_usr = _it["Leverler outlet manual"]
                if _it.__contains__("Leverler flexion manual"):
                    act_data.set_flexion_usr= _it["Leverler flexion manual"]
                if _it.__contains__("2nd Leverler inlet manual"):
                    act_data.set_inlet_mod = _it["2nd Leverler inlet manual"]
                if _it.__contains__("2nd Leverler outlet manual"):
                    act_data.set_outlet_mod=_it["2nd Leverler outlet manual"]
                if _it.__contains__("2nd Leverler flexion manual"):
                    act_data.set_flexion_mod = _it["2nd Leverler flexion manual"]


                if _it.__contains__("Full Length Gap Limit"):
                    act_data.full_length_limit = _it["Full Length Gap Limit"]
                if _it.__contains__("Full Cross Gap Limit"):
                    act_data.full_cross_limit=_it["Full Cross Gap Limit"]

                if act_data.full_length_limit < 0.00001:
                    act_data.full_length_limit = act_data.full_cross_limit
                elif act_data.full_cross_limit < 0.00001:
                    act_data.full_cross_limit = act_data.full_length_limit

                if _it.__contains__("pre flmg_mean"):
                    act_data.pred_full_length = _it["pre flmg_mean"]
                else:
                    log.info("{},missing flmg_mean ".format(_it["plate_id"]))
                    continue
                
                if _it.__contains__("pre fcmg_mean"):
                    act_data.pred_full_cross = _it["pre fcmg_mean"]
                else:
                    log.info("{},missing fcmg_mean ".format(_it["plate_id"]))
                    continue

                if _it.__contains__("Full Length Max Gap"):
                    act_data.meas_full_length=_it["Full Length Max Gap"]
                else:
                    log.info("{},missing full length ".format(_it["plate_id"]))
                    continue

                if _it.__contains__("Full Cross Max Gap"):
                    act_data.meas_full_cross=_it["Full Cross Max Gap"]
                else:
                    log.info("{},missing fullcross ".format(_it["plate_id"]))
                    continue

                if _it.__contains__("Cross 1m Max Gap"):
                    act_data.meas_cross_1m=_it["Cross 1m Max Gap"]
                else:
                    log.info("{},missing cross 2m ".format(_it["plate_id"]))
                    continue
                if _it.__contains__("Length 1m Max Gap"):
                    act_data.meas_length_1m=_it["Length 1m Max Gap"]
                else:
                    log.info("{},missing lenth 1m ".format(_it["plate_id"]))
                    continue
                if _it.__contains__("Length 2m Max Gap"):
                    act_data.meas_length_2m=_it["Length 2m Max Gap"]
                else:
                    log.info("{},missing lenth 2m ".format(_it["plate_id"]))
                    continue

                if _it.__contains__("ctime"):
                    act_data.timestamp = int(time.mktime(_it["ctime"].timetuple()))
                
                #log.info("### add act: {}".format( act_data.plate_id)) 
                log.info("[{}]:tm[{}],fl[{:.3},{:.3}],fc[{:.3},{:.3}]".format(act_data.plate_id, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(act_data.timestamp)),
                                                           act_data.pred_full_length,act_data.meas_full_length,
                                                           act_data.pred_full_cross,act_data.meas_full_cross))
                act_list.append(act_data)

                if len(EXP_FILE_NAME):
                    for nm in EXP_FIELD_NAMES:
                        if nm in _it:
                            if nm == "_id":
                                f.write("{},".format(timestamp_from_objectid(_it[nm])))
                            else:
                                f.write("{},".format(_it[nm]))
                        else:
                            f.write("NULL,")
                    f.write("\n")
                
                #限制记录数
                # idx += 1
                # if idx > MAX_COUNT:
                #     break
            
            if len(EXP_FILE_NAME):
                f.close()
            # log.info("ret.act type: {}".format(type(ret.act)))
            act_list.reverse()
            #log.info("act data size: {}".format(len(act_list)))
            

            for it in act_list:
                ret.act.append(it)
            # ret.act = act_list.reverse()
            # log.info("size: {}".format(len(act_list)))
            # for it in act_list:
            #     log.info("act: {}".format(it.plate_id))
            
            # log.info("act list type: {},{}".format(type(reversed(act_list)),type(act_list)))
            # ret.act = reversed(act_list)            

        except Exception as e:
            log.error("GetPlateActData:error",e)

        return ret

